define(function(require, exports, module) {
	var $ = require('jquery')
	require('jquery.html5uploader')
	require('../../lib/jquery.ztree/jquery.ztree.core-3.5.min')
	var Spine = require('spine')	
	var model = require('../model/model')
	var Location = model.Location
	var File = model.File
	var Upload = model.Upload
	var Directory = model.Directory	
	var zTree;
	var setting = {
		view: {
			dblClickExpand: false,
			showLine: true,
			selectedMulti: false,
		},
		async: {
			enable: true,
			contentType: 'application/json',
			url: '/ld',
			type: 'get',
			autoParam: ['name'],
			otherParam: {
				"path": "/"
			}
		},
		data: {
			simpleData: {
				enable: true,
				idKey: "id",
				pIdKey: "pId",
				rootPId: ""
			}
		},
		callback: {
			beforeAsync: function(treeId, treeNode) {
				var treeObj = $.fn.zTree.getZTreeObj("tree");
				try {
					treeNode.trac
				} catch (error) {
					return
				}
				treeObj.setting.async.otherParam.path = treeNode.trac
			},
			beforeClick: function(treeId, treeNode) {},
			onClick: function(event, treeId, treeNode) {

			},
			onAsyncSuccess: function(event, treeId, treeNode, msg) {},
			onNodeCreated: function(event, treeId, treeNode) {
				if (treeNode.getParentNode()) {
					if (treeNode.getParentNode().trac == '/') {
						treeNode.trac = '/' + treeNode.name
					} else {
						treeNode.trac = treeNode.getParentNode().trac + '/' + treeNode.name
					}
				}
			}
		}
	};

	var App = Spine.Controller.sub({
		elements: {
			'#new-folder': 'newFolder',
			'#browser-location': 'browserLocation',
			'#browser-viewer>ul': 'fileList',
			'#browser-table-header': 'browserTableHeader',
			'#download': 'downloadAction',
			'#rename': 'renameAction',
		},
		events: {
			'click #new-folder': 'createFolder',
			'click #delete': 'deleteFiles',
			'click #rename': 'renameFile',
			'click #download': 'downloadFiles',
			'click #move': 'moveFiles',
			'click #copy': 'copyFiles',
			'click #upload': 'uploadFiles'
		},
		init: function() {
			File.bind('create', this.proxy(this.appendFile))
			File.bind('refresh', this.proxy(this.addAllFiles))
			Location.bind('create', this.proxy(this.addLocation))
			Directory.bind('create', this.proxy(this.distFiles))
			FileItem.bind('operate', this.proxy(this.filterAction))
			App.bind('open', this.proxy(this.openFile))
			Location.create({
				'name': 'Home',
				'path': '/'
			})
			File.fetchByPath('/')
		},
		createFolder: function() {
			$.post('/create', {
				'path': App.getCurrentLocation() + 'New Folder',
				'filename': 'New Folder'
			}, function(data) {
				File.create({
					'filename': data.filename,
					'type': data.type,
					'modTime': data.modTime,
					'path': data.path
				});
			}, 'json');
			return true
		},
		addFile: function(file) {
			var newFile = new FileItem({
				model: file
			})
			newFile.render().el.appendTo(this.fileList)
			return newFile.render().el
		},
		appendFile: function(file) {
			if (file.type == 'folder') {
				this.addFile(file).addClass('editing new selected').find('.filename-edit').first().focus()
			} else {
				this.addFile(file)
			}
		},
		addAllFiles: function() {
			return File.each(this.proxy(this.addFile))
		},
		deleteFiles: function() {
			$('li.file').each(function(i, r) {
				if ($(r).hasClass('selected')) {
					$(r).tmplItem().data.destroy(true)
				}
			})
			this.filterAction()
		},
		renameFile: function() {
			this.fileList.children('.selected').first().addClass('editing').find('.filename .filename-edit').first().focus()
		},
		downloadFiles: function() {
			var pendingFiles = this.findSlectedFile()
			var files = []
			if (pendingFiles.length == 1) {
				pendingFiles.first().tmplItem().data.controller.download()
			} else {
				pendingFiles.each(function(index, file) {
					r = $(file).tmplItem().data
					files.push({
						'filename': r.filename,
						'type': r.type,
						'path': r.path
					})
				})
				$.post('/downloads', {
					'files': JSON.stringify(files),
					'type': 'mixed'
				}, function(data) {
					window.location.href = data.export_url
				}, 'json')
			}
		},
		openFile: function(file) {
			if (file['type'] == 'folder') {
				zTree
				Location.create({
					'name': file.name,
					'path': file.path
				})
				File.destroyAll(false)
				File.fetchByPath(file.path)
			}
		},
		moveFiles: function() {
			Directory.create({
				'type': 'Move',
				'path': App.getCurrentLocation()
			})
		},
		copyFiles: function() {
			Directory.create({
				'type': 'Copy',
				'path': App.getCurrentLocation()
			})
		},
		distFiles: function(directory) {
			var directoryItem = new DirectoryItem({
				model: directory
			})
			$.fancybox(directoryItem.render().el)
			var t = $("#tree");
			var nodes = [{
				id: 0,
				pId: 0,
				name: "Home",
				isParent: true
			}]
			t = $.fn.zTree.init(t, setting, nodes)
			t.getNodes()[0].trac = '/'
		},
		uploadFiles: function() {
			var u = Upload.create({
				'name': 'Home',
				'path': '/'
			})
			var ui = new UploadControl({
				model: u
			})
			$.fancybox(ui.render().el)
			$('#fileinput-button>input').html5Uploader({
				name: "file",
				postUrl: "/uploads",
				path: App.getCurrentLocation(),
				onClientAbort: function() {

				},
				onClientError: function() {

				},
				onClientLoad: function(event, file) {

				},
				onClientLoadEnd: function() {

				},
				onClientLoadStart: function(event, file) {
					file.context = $('#uploadFileTemplate').tmpl({
						name: file.name,
						size: readablizeBytes(file.size),
						folder: App.getCurrentFolder()
					}).appendTo($('#upload-file-list'))
					$(file.context[0]).find('.status').first().addClass('status-loading')
				},
				onClientProgress: function() {

				},
				onServerAbort: function() {

				},
				onServerError: function() {
					$(file.context[0]).find('.status').first().removeClass('status-loading').addClass('status-error')
				},
				onServerLoad: function() {

				},
				onServerLoadStart: function(event, file) {},
				onServerProgress: function(event, file) {
					var progress = parseInt(event.loaded / event.total * 100, 10)
					$(file.context[0]).find('.progress-bar').css('width', progress + '%')

				},
				onServerReadyStateChange: function(event, file) {},
				onSuccess: function(event, file, data) {
					var record = JSON.parse(data)
					File.create({
						'filename': record.filename,
						'type': record.type,
						'modTime': record.modTime,
						'path': record.path
					});
					$(file.context[0]).find('.status').first().removeClass('status-loading').addClass('status-success')
				}
			})
		},
		addLocation: function(loc) {
			var newLoc = new LocationItem({
				model: loc
			})
			return this.browserLocation.append(newLoc.render().el)
		},
		filterAction: function() {
			var selectedItemsLength = this.findSlectedFile().length
			this.renameAction.parent().toggleClass('disabled', selectedItemsLength > 1)
			this.browserTableHeader.toggleClass('selected', selectedItemsLength > 0)
		},
		findSlectedFile: function() {
			return this.fileList.children('.selected')
		}
	})
	App.extend(Spine.Events)
	App.extend({
		getCurrentLocation: function() {
			var current = $('#browser-location a').last().tmplItem().data.path
			if (current.charAt(current.length - 1) != '/') {
				current += '/'
			}
			return current.toString()
		},
		getCurrentFolder: function() {
			return $('#browser-location a').last().tmplItem().data.name
		}
	})

		function readablizeBytes(bytes) {
			var s = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
			var e = Math.floor(Math.log(bytes) / Math.log(1024));
			return (bytes / Math.pow(1024, Math.floor(e))).toFixed(2) + " " + s[e];
		}

	module.exports = App
	
	var FileItem = require('./fileitem')
	var LocationItem = require('./locationitem')
	var UploadControl = require('./uploadcontrol')
	var DirectoryItem = require('./directoryitem')
})